package com.huahua.api.service.utility.impl;

import com.huahua.api.entity.base.QiNiuOssUploadBean;
import com.huahua.api.entity.param.QrCodeGenerateParam;
import com.huahua.api.exception.CommonException;
import com.huahua.api.service.utility.QrCodeService;
import com.huahua.api.util.CheckUtil;
import com.huahua.api.util.QRCodeWithLogoUtil;
import com.huahua.api.util.QiNiuUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.hutool.extra.qrcode.QrCodeUtil;
import org.dromara.hutool.extra.qrcode.QrConfig;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;

import java.io.ByteArrayInputStream;
import java.util.UUID;

/**
 * 二维码生成服务实现
 *
 * @author Huahua-Ai
 * @date 2025-08-23 15:35:00
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class QrCodeServiceImpl implements QrCodeService {

    private final QiNiuUtils qiNiuUtils;
    private final QRCodeWithLogoUtil qrCodeWithLogoUtil;

    @Override
    public Mono<String> generateQrCode(QrCodeGenerateParam param) {
        return Mono.fromCallable(() -> {
                    // 参数校验
                    CheckUtil.checkStrNotBlank(param.getContent(), "二维码内容不能为空");
                    CheckUtil.checkTrue(param.getSize() > 0 && param.getSize() <= 1000, "二维码大小必须在1-1000之间");
                    CheckUtil.checkTrue(param.getMargin() >= 0 && param.getMargin() <= 10, "二维码边距必须在0-10之间");

                    try {
                        // 生成文件名
                        String fileName = "qr_" + System.currentTimeMillis() + "_" + UUID.randomUUID().toString().substring(0, 8);

                        // 获取是否去除白边的设置
                        boolean removeWhiteBorder = param.getRemoveWhiteBorder() != null ? param.getRemoveWhiteBorder() : true;

                        // 判断是否需要添加Logo
                        if (param.getLogoUrl() != null && !param.getLogoUrl().isEmpty()) {
                            // 设置Logo尺寸
                            int logoWidth = param.getLogoWidth() != null ? param.getLogoWidth() : param.getSize() / 5;
                            int logoHeight = param.getLogoHeight() != null ? param.getLogoHeight() : param.getSize() / 5;

                            // 使用带Logo的QR码生成器
                            String url = qrCodeWithLogoUtil.generateQrCodeWithLogoAndUpload(
                                    param.getContent(),
                                    param.getSize(),
                                    param.getSize(),
                                    param.getLogoUrl(),
                                    logoWidth,
                                    logoHeight,
                                    fileName,
                                    removeWhiteBorder
                            );

                            log.info("带Logo的二维码生成成功: {}", url);
                            return url;
                        } else if (removeWhiteBorder) {
                            // 需要去除白边，使用QRCodeWithLogoUtil
                            String url = qrCodeWithLogoUtil.generateQrCodeAndUpload(
                                    param.getContent(),
                                    param.getSize(),
                                    param.getSize(),
                                    fileName,
                                    removeWhiteBorder
                            );

                            log.info("去除白边的二维码生成成功: {}", url);
                            return url;
                        } else {
                            // 使用原有的Hutool方式生成普通二维码（保留白边）
                            QrConfig config = new QrConfig(param.getSize(), param.getSize());
                            config.setMargin(param.getMargin());
                            byte[] bytes = QrCodeUtil.generatePng(param.getContent(), config);

                            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
                            QiNiuOssUploadBean uploadResult = qiNiuUtils.uploadFileByStream(bais, fileName, "png");

                            if (uploadResult == null || uploadResult.getUrl() == null) {
                                throw new CommonException("二维码上传失败");
                            }

                            log.info("二维码生成成功: {}", uploadResult.getUrl());
                            return uploadResult.getUrl();
                        }
                    } catch (Exception e) {
                        log.error("二维码生成失败", e);
                        throw new CommonException("二维码生成失败: " + e.getMessage());
                    }
                })
                .subscribeOn(Schedulers.boundedElastic());
    }
}
